﻿#light
module GenericCurrying
open System
open CSharpRef

// this is no good, can't use it
//module FuncExtensions =
//    type Func<'a, 'b> with
//        member x.Curried
//            with get() =
//                0
//    type Func<'a, 'b, 'c> with
//        member x.Curried
//            with get() =
//                0

// the following does not compile:
// This runtime coercion or type test from type  'a  to   'b * 'c -> 'd involves an indeterminate type based on information prior to this program point. Runtime type tests are not allowed on some types. Further type annotations are needed.	
//module Currying = 
//    let curry = function
//                | :? (_*_ -> _) as f -> fun a b -> f(a,b)

type FP =
    static member curry2 (f:_*_ -> _) = 
        fun a b -> f (a,b)

    static member curry (f:_*_ -> _) = 
        FP.curry2 f

    static member curry3 (f:_*_*_ -> _) = 
        fun a b c -> f (a,b,c)
        
    static member curry (f:_*_*_ -> _) = 
        FP.curry3 f
        
    static member curry4 (f:_*_*_*_ -> _) = 
        fun a b c d -> f (a,b,c,d)

    static member curry (f:_*_*_*_ -> _) = 
        FP.curry4 f
        
    static member curry5 (f:_*_*_*_*_ -> _) = 
        fun a b c d e -> f (a,b,c,d,e)

    static member curry (f:_*_*_*_*_ -> _) = 
        FP.curry5 f
        
    static member curry6 (func:_*_*_*_*_*_ -> _) = 
        fun a b c d e f -> func (a,b,c,d,e,f)

    static member curry (func:_*_*_*_*_*_ -> _) = 
        FP.curry6 func
        
